package dk.snaveponyklub.persist.impl;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.Namespace;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;
import org.jdom.xpath.XPath;

import dk.snaveponyklub.handler.HandlerFactory;
import dk.snaveponyklub.util.Logger;


public class TimeSlotCacheImpl {

	Namespace ns = Namespace.getNamespace("s", "http://www.snaveponyklub.dk");
    XMLLoaderImpl loader = new XMLLoaderImpl();
    XMLValidator validator = new XMLValidator();
    Document timeslots;

	public TimeSlotCacheImpl()
	{
		refreshCache();
	}

	private void refreshCache() {
		timeslots = loader.loadTimeslotsDocument();
	}

	private SimpleDateFormat xmlTimeFormatter = new SimpleDateFormat("yyyy-MM-dd'T'kk:mm:ss");

	public String formatXMLTime(Date time) {
		return xmlTimeFormatter.format(time);
	}

	public Date createXMLTime(int year, int month, int date, int hour, int min, int sec) {
		Calendar cal = Calendar.getInstance();
		cal.clear();
		cal.set(Calendar.YEAR, year);
		cal.set(Calendar.MONTH, month);
		cal.set(Calendar.DATE, date);
		cal.set(Calendar.HOUR_OF_DAY, hour);
		cal.set(Calendar.MINUTE, min);
		cal.set(Calendar.SECOND, sec);
		return cal.getTime();
	}

	public Date createXMLTime(int year, int week, int dayOfWeek, int hour) {
		Calendar cal = GregorianCalendar.getInstance();
		cal.clear();
		cal.set(Calendar.YEAR, year);
		cal.set(Calendar.WEEK_OF_YEAR, week);
		cal.add(Calendar.DATE, dayOfWeek-1);
		cal.add(Calendar.HOUR_OF_DAY, hour);
		return cal.getTime();
	}
	
    public Element getTimeSlot(Date starttime, Date endtime ) {
		String startTimeStr = formatXMLTime(starttime);
		String endTimeStr = formatXMLTime(endtime);
		
        try {
            XPath xp = XPath.newInstance("//s:timeslot[@starttime='" + startTimeStr + "' and @endtime='" + endTimeStr + "']");
            xp.addNamespace(ns);
            Element timeslotNode = (Element)xp.selectSingleNode(timeslots);
            return timeslotNode;
        } catch (JDOMException e) {
            e.printStackTrace();
        }
        return null;
    }

    public Element getTimeSlots(int week) {
        try {
            XPath xp = XPath.newInstance("//s:timeslots");
            xp.addNamespace(ns);
            Element timeslotNode = (Element)xp.selectSingleNode(timeslots);
            return timeslotNode;
        } catch (JDOMException e) {
            e.printStackTrace();
        }
        return null;
    }

    public Element getTimeSlots() {
        try {
            XPath xp = XPath.newInstance("//s:timeslots");
            xp.addNamespace(ns);
            Element timeslotsElement = (Element)xp.selectSingleNode(timeslots);
            return timeslotsElement;
        } catch (JDOMException e) {
            e.printStackTrace();
        }
        return null;
    }

    public void addTimeslot(String xml) throws Throwable {
    	try {
    		if (validator.isValid(xml, "Persist.xsd")) {
    			Document document = loader.loadXml(xml);
	            XPath xp = XPath.newInstance("//s:timeslots/s:timeslot");
	            xp.addNamespace(ns);
	            Element timeslot = (Element)xp.selectSingleNode(document);
	            timeslot.setAttribute("id", getNextId());
	            
	        	xp = XPath.newInstance("//s:timeslots");
	        	xp.addNamespace(ns);
				Element timeslotsElement = (Element)xp.selectSingleNode(timeslots);            
				timeslotsElement.addContent((Element)timeslot.clone());
	            loader.writeTimeslots(timeslots);
	    		refreshCache();
    		} else { 
    			throw new Throwable("Not valid timeslot");
    		}
        } catch (JDOMException e) {
            e.printStackTrace();
		}
    }
    
    public String getNextId() {
    	int maxId = 1;
        try {
            XPath xp = XPath.newInstance("//s:timeslots/s:timeslot");
            xp.addNamespace(ns);
            @SuppressWarnings("unchecked")
			List<Element> elements = xp.selectNodes(timeslots);

            for (Element element : elements) {
                try {
                    int id = Integer.parseInt(element.getAttributeValue("id"));
                    if (id > maxId) {
                    	maxId = id;
                    }
                } catch (NumberFormatException e) {
                    Logger.error("Error get id from timeslot");
                }
			}
        } catch (JDOMException e) {
            e.printStackTrace();
        }
        return (maxId+1)+"";
    }
	public static void main(String[] args) throws IOException, Throwable {
		TimeSlotCacheImpl cache = new TimeSlotCacheImpl();
//		
//		Date time1 = cache.createXMLTime(2010, 35, 5, 16);
//		Date time2 = cache.createXMLTime(2010, 35, 5, 17);
//		System.out.println(cache.formatXMLTime(time1));
//		System.out.println(cache.formatXMLTime(time2));
//		
//    	Element timeslot = cache.getTimeSlot(time1, time2);
//    	Element timeslot = cache.getTimeSlot(new Date(), new Date());
//    	Element timeslot = cache.getTimeSlots(1);
//    	
//        XMLOutputter xo = new XMLOutputter();
//        xo.output(timeslot, System.out);
        
       String xml = "<s:persist xmlns:s='http://www.snaveponyklub.dk'><s:timeslots><s:timeslot endtime='endtime' starttime='2010-10-07T11:00:00' id='4'><s:person>1</s:person></s:timeslot></s:timeslots></s:persist>";
       HandlerFactory.getInstance().addTimeslot(xml);
       //cache.addTimeslot(xml);
        
       XMLOutputter xo = new XMLOutputter();
       xo.setFormat(Format.getPrettyFormat());
       xo.output(cache.getTimeSlots(), System.out);
    }	
    
}
